package bat.ke.qq.com.tx;

import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;


/**
 * 编程式事务
 */
public class SpringTransactionExample {
    private static String url = "jdbc:mysql://127.0.0.1:3306/test";
    private static String user = "root";
    private static String password = "123456";


    public static void main(String[] args) {
        // 获取数据源
        final DataSource ds = new DriverManagerDataSource(url, user, password);
        // 编程式事务
        final TransactionTemplate template = new TransactionTemplate();
        // 设置事务管理器
        template.setTransactionManager(new DataSourceTransactionManager(ds));
        template.execute(status -> {
            Connection conn = DataSourceUtils.getConnection(ds);
            Object savePoint = null;
            try {
                {
                    // 插入
                    PreparedStatement prepare = conn.
                            prepareStatement(
                                    "insert INTO account (accountName,user,money) VALUES (?,?,?)");
                    prepare.setString(1, "111");
                    prepare.setString(2, "aaa");
                    prepare.setInt(3, 10000);
                    prepare.executeUpdate();
                }
                // 设置保存点
                savePoint = status.createSavepoint();
                {
                    // 插入
                    PreparedStatement prepare = conn.
                            prepareStatement(
                                    "insert INTO account (accountName,user,money) VALUES (?,?,?)");
                    prepare.setString(1, "222");
                    prepare.setString(2, "bbb");
                    prepare.setInt(3, 10000);
                    prepare.executeUpdate();
                }
                {
                    // 更新
                    PreparedStatement prepare = conn.prepareStatement(
                            "UPDATE account SET money= money+1 where user=?");
                    prepare.setString(1, "aaa");
                    prepare.executeUpdate();
                    int i = 1 / 0;
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("更新失败");
                if (savePoint != null) {
                    status.rollbackToSavepoint(savePoint);
                } else {
                    status.setRollbackOnly();
                }
            }
            return null;
        });
    }


}
